#ifndef COMMON_SYNCOBJECT_H
#define COMMON_SYNCOBJECT_H


#include "error.h"
#include <string>
using namespace std;

namespace common {

class SyncObject {
  public:
    //Number of sync objects we can wait for.
    static unsigned char maximumWaitObjects;

    //Value for infinite waits.
    static unsigned int infiniteWait;

    //Waits for multiple sync objects.
    virtual Error::code WaitForMultiple(unsigned int count, const SyncObject * handleList, bool waitAll, unsigned int milliseconds) = 0;

    //Standard wait for single sync object
    virtual Error::code WaitFor(unsigned int timeout) = 0;

};
class Event : public SyncObject {
  public:
    //Creates new event.
    //@param manualReset If true, then this object has to be set to non-signaled manualy trough Reset
    //@param initialState If true initial state is signaled.
    //@param name Name of the object
    Error::code Create(bool manualReset, bool initialState, string name);

    //Opens named mutex if such exists.
    Error::code Open(string name);

    //Manualy resets signaled object to non-signaled state.
    Error::code Reset();

    //Changes object to signaled state.
    Error::code Set();

};
class Mutex : public SyncObject {
  public:
    //Creates new mutex. If initialOwner is true, this thread will gain ownership of this mutex.
    virtual Error::code Create(bool initialOwner, string name) = 0;

    //Opens named mutex if such exists.
    virtual Error::code Open(string name) = 0;

    //Releases owned mutex.
    virtual Error::code Release() = 0;

};
class Semaphore : public SyncObject {
  public:
    Error::code Create(unsigned int initialCount, unsigned int maximumCount, const string & name);

    //Opens existing semaphore.
    Error::code Open(const string & name);

    //Increases the count of the specified semaphore object by a specified amount.
    Error::code Release(unsigned int releaseCount, unsigned int & previousCount);

};

} // namespace common
#endif
